use thiserror::Error;

pub const STATUS_OK: i16 = 0;
pub const STATUS_PERM_FAILURE: i16 = 1;
pub const STATUS_TOO_MANY_RETRIES: i16 = 2;
pub const STATUS_DECODE_FAILURE: i16 = 3;

/// Error as a result of actually running a job.
#[derive(Debug, Error)]
pub enum JobError {
    #[error("not yet implemented")]
    Unimplemented,

    /// Generic unrecovereable error with a custom ID.
    #[error("{1}")]
    CustomUnrecoverable(i16, String),

    /// Recoverable error that has a message stored on excessive retries.
    #[error("{0}")]
    OtherRecoverable(String),

    #[error("{0}")]
    Other(String),
}

impl JobError {
    /// Returns if the job can be retried after some delay.
    pub fn is_retryable(&self) -> bool {
        match self {
            Self::OtherRecoverable(_) => true,
            _ => false,
        }
    }

    pub fn status_code(&self) -> i16 {
        match self {
            Self::Unimplemented => 255,
            Self::CustomUnrecoverable(status, _) => *status,
            Self::OtherRecoverable(_) => 2,
            _ => 1,
        }
    }
}
